package com.ogawa.base.download;





import java.util.concurrent.PriorityBlockingQueue;

/**
 * Created by fhb on 2016/4/8.
 * 下载线程池
 */
public final class DownloadThreadPool {

    private static DownloadThreadPool mInst = null;
    private static int WORKER_NUM = 3;//最多允许几个线程在工作,默认3个
    //优先级队列
    private PriorityBlockingQueue<IRequest> mNetworkQueue = new PriorityBlockingQueue<IRequest>();
    //工作者线程
    public PoolWorker[] mWorkers;

    private DownloadThreadPool( ) {
        mWorkers = new PoolWorker[WORKER_NUM];
        for (int i = 0; i < mWorkers.length; i++) {
            mWorkers[i] = new PoolWorker();
        }
    }

    public static DownloadThreadPool getInstance() {
        if (mInst == null){
            synchronized (DownloadThreadPool.class) {
                if(mInst == null){
                    mInst = new DownloadThreadPool();
                }
            }
        }
        return mInst;
    }

    //不能在下载的地方直接调用，要在downloadmanager里面调用，因为这里没有任务去重
    public void addTask(IRequest req) {
        synchronized (mNetworkQueue) {
            mNetworkQueue.add(req);
            mNetworkQueue.notifyAll();
        }
    }

    public void removeTask(IRequest req){
        synchronized (mNetworkQueue) {
            mNetworkQueue.remove(req);
            mNetworkQueue.notifyAll();
        }
    }

    public synchronized void destroy() {
        for (int i = 0; i < WORKER_NUM; i++) {
            mWorkers[i].stopWorker();
            mWorkers[i] = null;
        }
        mNetworkQueue.clear();
    }

    private class PoolWorker extends Thread {
        private boolean isRunning = true;
        public PoolWorker() {
            start();
        }

        public void stopWorker() {
            this.isRunning = false;
        }

        public void run() {
            while (isRunning) {
                IRequest r = null;
                try{
                    synchronized (mNetworkQueue) {
                        while(mNetworkQueue.isEmpty()){
                            try{
                                mNetworkQueue.wait(30);
                            }catch(Exception e){
                            }
                        }
                        r = mNetworkQueue.take();
                    }
                    if(r != null){
                        r.execute();
                    }
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

}
